/*
 * author      : 吴中勤 
 * date        : 2018/9/16
 * description : 通用消息处理
 */

package com.deepexi.adapter.converter.sap;

import com.deepexi.adapter.common.CommonUtils;
import com.deepexi.adapter.common.StringUtil;
import com.deepexi.adapter.facade.moby.request.MobyEventBody;
import com.deepexi.adapter.facade.moby.response.BaseResponseBody;
import com.deepexi.adapter.log.Log4Request;
import com.deepexi.adapter.log.LogRecorderImpl;
import com.deepexi.adapter.mq.MessageHandler;
import com.deepexi.adapter.mq.TopicEnum;
import com.deepexi.adapter.sdk.sap.exception.SapBizException;
import com.google.gson.JsonSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MobyMessageHandler implements MessageHandler {

    private static final Logger logger = LoggerFactory.getLogger(MobyMessageHandler.class);

    @Autowired
    private MobyEventHandler4Sap eventHandler;

    @Autowired
    private SapConverterContext converterContext;

    @Autowired
    private MobyEventBodyCheck checker;

    @Autowired
    private LogRecorderImpl logRecorder;

    public void handleMessage(String topic, String msg) {
        Log4Request log = new Log4Request();
        TopicEnum topicEnum = TopicEnum.getByTopic(topic);
        if (null == topicEnum)
            throw new RuntimeException("不支持的topic" + topic);

        log.setKeyword1(topicEnum.desc);
        log.setKeyword2("mq");
        log.setFromSide("moby")
                .setToSide("adapter")
                .setApiType(topic)
                .setReqId("")
                .setUrl("")
                .setRequest(msg);
        Long start = System.currentTimeMillis();

        MobyEventBody eventBody = null;
        try {
            eventBody = parseMessage(topic, msg);
            log.setMobyOrderId(eventBody.getMobyTradeOrder().getId());
            log.setShopCode(eventBody.getMobyTradeOrder().getShopCode());
            log.setKeyword3(eventBody.getMobyMember().getName());

            BaseResponseBody responseBody = handleMsgInternal(topic, eventBody);
            log.setResponse(responseBody.toString());
        } catch (Exception ex) {
            ex.printStackTrace();
            String errMsg = "消息处理失败:" + ex.toString();
            logger.error(errMsg);
            log.setErrorStr(errMsg);
        }

        log.setTimeCost(System.currentTimeMillis() - start);
        logRecorder.record(log);
    }


    private MobyEventBody parseMessage(String topic, String msg) throws SapBizException {
        if (StringUtil.isNullorEmpty(msg)) {
            String errMsg = "消息体无效,topic=" + topic;
            logger.error(errMsg);
            throw new SapBizException("消息体不能为null/empty");
        }

        MobyEventBody body = null;
        try {
            body = CommonUtils.jsonString2Obj(msg, MobyEventBody.class);
        } catch (JsonSyntaxException ex) {
            String errMsg = "消息体不能转换为 MobyEventBody,topic=" + topic + ", msg=" + msg;
            logger.error(errMsg);
            throw new SapBizException(errMsg);
        }

        /* 这个消息比较大, 一开始就分配大一点空间 现在可以观察到 ~ 20K */
        StringBuilder sb = new StringBuilder(30 * 1024);

        /* 支付订金 不需要检验用户 */
        if (!checker.checkMobyEventBody(topic, body, sb, TopicEnum.MOBY_DEPOSIT_PAID_ONCE.topic.equals(topic))) {
            String errMsg = "消息未能通过 有效性校验, 提示内容为=" + sb.toString() + ", msg=" + msg;
            logger.error(errMsg);
            throw new SapBizException(errMsg);
        }

        return body;
    }

    private BaseResponseBody handleMsgInternal(String topic, MobyEventBody body) throws Exception {

        TopicEnum topicEnum = TopicEnum.getByTopic(topic);
        if (null == topicEnum)
            throw new RuntimeException("不支持的消息 topic=" + topic);

        converterContext.getLogContext().setKeyword3(body.getMobyMember().getName());
        converterContext.getLogContext().setKeyword2("http");

        logger.info(" ====== 收到消息: {} ====== ", topicEnum.desc);
        switch (topicEnum) {

            // 付订金
            case MOBY_DEPOSIT_PAID_ONCE:
                // case MOBY_DEPOSIT_FULFIL:
                return eventHandler.onDepositPaid(body);

            // 订转定
            case MOBY_DEPOSIT_CONVERT:
                return eventHandler.onCoolingOffPeriodEnded(body);

            // 金融确定
            case MOBY_MAKE_LOAN_SUCCESS:
                return eventHandler.onLoanConfirmed(body);

            // 收到首付
            case DOWN_PAYMENT_PAID_ONCE:
                return eventHandler.onDownPaymentConfirmed(body);

            // billing
            case MOBY_ORDER_BILLING:
                return eventHandler.onBilling(body);

            // 确认尾款(全款)
            case FINAL_PAYMENT_PAID_ONCE:
                return eventHandler.onFinalPaymentConfirmed(body);

            // 提供精品保险
            case MOBY_PROVIDE_GIFT:
                return eventHandler.onOfferBoutiqueOrMaintain(body);

            // 保险确认
            case MOBY_UPLOAD_INSURANCE_POLICY:
                return eventHandler.onInsuranceConfirmed(body);

            // 精品变更
            case MOBY_BOUTIQUE_CHANGE:
                return eventHandler.onBoutiqueChanged(body);

            // 退款完成
            case MOBY_REFUND_DEPOSIT:
                eventHandler.onDepositRefunded(body);

                // 顾问变更
            case MOBY_CONSULT_CHANGE:
                return eventHandler.onConsultChanged(body);

            // 锁车成功
            case MOBY_VEHICLE_LOCK_SUCCESS:
                return eventHandler.onVehicleLocked(body);

            // 精品出库
            case MOBY_STOCK_OUT_BOUTIQUE:
                return eventHandler.onBoutiqueStockOut(body);

            // 车辆出库
            case MOBY_STOCK_OUT_VEHICLE:
                return eventHandler.onVehicleStockOut(body);

            default:
                throw new RuntimeException("不支持的消息 topic=" + topic);
        }
    }
}
